package com.mapler.autoresponder.service;

import com.mapler.service.*;
import java.util.*;
import javax.mail.*;
import javax.mail.Flags.Flag;
import javax.mail.internet.MimeMessage;
import javax.mail.search.FlagTerm;
import org.apache.log4j.Logger;

public class IMAPAutoReader {

    INotifier iNotifier;
    EmailModel emailModel;
    Folder inbox;
    Store store;
    ArrayList<MimeMessage> eMessages;
    private static Logger log = Logger.getLogger(IMAPAutoResponder.class);

    public IMAPAutoReader(INotifier iNotifier, EmailModel emailModel) {
        this.iNotifier = iNotifier;
        this.emailModel = emailModel;
    }

    IMAPAutoReader() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public void connect() {
        try {
            /* Set the mail properties */
            iNotifier.notify("Going to read email inbox");

            Properties props = System.getProperties();
            props.setProperty("mail.store.protocol", "imaps");

            Session session;
            if (emailModel.isAuto()) {
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.starttls.enable", "true");
                props.put("mail.smtp.host", emailModel.getSmtphost());
                props.put("mail.smtp.port", emailModel.getSmtpport());

                session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(emailModel.getUsername(), emailModel.getPassword());
                    }
                });
            } else {
                session = Session.getDefaultInstance(props, null);
            }

            /* Create the session and get the store for read the mail. */
            iNotifier.notify("Going to connect mail server");

            //Session session = Session.getDefaultInstance(props,null);
            store = session.getStore("imaps");

            store = session.getStore("imaps");
            if (emailModel.getUsername().contains("@gmail")) {
                store.connect("imap.gmail.com", emailModel.getUsername(), emailModel.getPassword());
            } else if (emailModel.getUsername().contains("@yahoo")) {
                store.connect("imap.mail.yahoo.com", emailModel.getUsername(), emailModel.getPassword());
            }
        } catch (Exception ex) {
        }
    }

    public void disconnect() {
        try {
            inbox.close(true);
            store.close();
        } catch (Exception ex) {
        }
    }

    public synchronized ArrayList<MimeMessage> read() {
        try {
            this.connect();
            eMessages = new ArrayList<MimeMessage>();
            /* Set the mail properties */
            iNotifier.notify("Going to read email inbox");

            /* Mention the folder name which you want to read. */
            inbox = store.getFolder("Inbox");
            int unReadMCount = inbox.getUnreadMessageCount();
            iNotifier.notify("No of Unread Messages : " + unReadMCount);
            if (unReadMCount == 0) {
                return eMessages;
            }
            /* Open the inbox using store. */
            inbox.open(Folder.READ_ONLY);
            //inbox.open(Folder.READ_WRITE);
            /* Get the messages which is unread in the Inbox */
            Message messages[] = inbox.search(new FlagTerm(new Flags(Flag.SEEN), false));
            /* Use a suitable FetchProfile */
            FetchProfile fp = new FetchProfile();
            fp.add(FetchProfile.Item.ENVELOPE);
            fp.add(FetchProfile.Item.CONTENT_INFO);
            inbox.fetch(messages, fp);
            for (Message m : messages) {
                MimeMessage _m = (MimeMessage) m;
                eMessages.add(_m);
            }
            //inbox.setFlags(messages, new Flags(Flags.Flag.SEEN), true);
            if (!emailModel.isAuto()) {
              this.disconnect();  
            }
        } catch (NoSuchProviderException ex) {
            log.debug("readMail :: Error on NoSuchProviderException " + ex);
            iNotifier.notify("Exception arise at the time of read mail");
            ex.printStackTrace();
        } catch (MessagingException ex) {
            log.debug("readMail :: Error on MessagingException " + ex);
            iNotifier.notify("Exception arise at the time of read mail");
            ex.printStackTrace();
        } catch (Throwable ex) {
            log.debug("readMail :: Error on MessagingException " + ex);
            iNotifier.notify("Exception arise at the time of read mail");
            ex.printStackTrace();
        }
        return eMessages;
    }
}
